﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace ConsoleApplication1
{
    class ChromaKeyer
    {
        public void keyColorFromImage()
        {
            Bitmap input = new Bitmap(@"D:\xbox.jpg");

            Bitmap output = new Bitmap(input.Width, input.Height);

            Console.WriteLine("Keying");
            // Iterate over all pixels from top to bottom...
            for (int y = 0; y < output.Height; y++)
            {
                //Console.WriteLine("Line "+y);
                // ...and from left to right
                for (int x = 0; x < output.Width; x++)
                {


                    // Determine the pixel color
                    Color camColor = input.GetPixel(x, y);
                    //Console.WriteLine("X: " + x +" Y: "+y+" | "+camColor.R+", "+camColor.G+", "+camColor.B);
                    // Every component (red, green, and blue) can have a value from 0 to 255, so determine the extremes
                    byte max = Math.Max(Math.Max(camColor.R, camColor.G), camColor.B);
                    byte min = Math.Min(Math.Min(camColor.R, camColor.G), camColor.B);

                    byte toleranz = 70;
                    byte halbeSichtbarkeit = 80;
                    byte viertelSichtbarkeit = 90;
                    Color replaceableColor = (Color)ColorTranslator.FromHtml("#FF77ff4e");


                    /*// Should the pixel be masked/replaced?
                    bool replace =
                        camColor.G != min // green is not the smallest value
                        && (camColor.G == max // green is the biggest value
                        || max - camColor.G < 8) // or at least almost the biggest value
                        && (max - min) > 96; // minimum difference between smallest/biggest value (avoid grays)
                    */

                    bool replace = camColor.R >= replaceableColor.R-toleranz &&
                        camColor.R <= replaceableColor.R + toleranz &&
                        camColor.G >= replaceableColor.G - toleranz &&
                        camColor.G <= replaceableColor.G + toleranz &&
                        camColor.B >= replaceableColor.B - toleranz &&
                        camColor.B <= replaceableColor.B + toleranz &&
                        camColor.A > 0;

                    if (replace)
                    {
                        camColor = Color.FromArgb(0, camColor);

                    }
                    /*
                    else
                    {
                        bool halbSichtbar = camColor.R >= replaceableColor.R - halbeSichtbarkeit &&
                            camColor.R <= replaceableColor.R + halbeSichtbarkeit &&
                            camColor.G >= replaceableColor.G - halbeSichtbarkeit &&
                            camColor.G <= replaceableColor.G + halbeSichtbarkeit &&
                            camColor.B >= replaceableColor.B - halbeSichtbarkeit &&
                            camColor.B <= replaceableColor.B + halbeSichtbarkeit &&
                            camColor.A > 0;

                        if (halbSichtbar)
                        {
                            camColor = Color.FromArgb(128, camColor);

                        }
                        else
                        {
                            bool viertelSichtbar = camColor.R >= replaceableColor.R - viertelSichtbarkeit &&
                                camColor.R <= replaceableColor.R + viertelSichtbarkeit &&
                                camColor.G >= replaceableColor.G - viertelSichtbarkeit &&
                                camColor.G <= replaceableColor.G + viertelSichtbarkeit &&
                                camColor.B >= replaceableColor.B - viertelSichtbarkeit &&
                                camColor.B <= replaceableColor.B + viertelSichtbarkeit &&
                                camColor.A > 0;

                            if (viertelSichtbar)
                            {
                                camColor = Color.FromArgb(64, camColor);

                            }
                        }
                        
                    }
                    */
                    

                    /*for (int deltaX = -1; deltaX <= 1; deltaX++)
                    {
                        for (int deltaY = -1; deltaY <= 1; deltaY++)
                        {
                            input.GetPixel(x + deltaX, y + deltaY);
                        }
                    }*/


                    // Set the output pixel
                    output.SetPixel(x, y, camColor);

                }
            }


            Console.WriteLine("Blur - Erste Stufe");
            // Iterate over all pixels from top to bottom... Blur Stufe 1
            for (int y = 0; y < output.Height; y++)
            {
                //Console.WriteLine("Line "+y);
                // ...and from left to right
                for (int x = 0; x < output.Width; x++)
                {

                    if (input.GetPixel(x, y).A == 255)
                    {

                        Boolean blur = false;

                        for (int deltaX = -1; deltaX <= 1; deltaX++)
                        {
                            for (int deltaY = -1; deltaY <= 1; deltaY++)
                            {
                                if (x + deltaX > -1 && x + deltaX < output.Width && x + deltaX > -1 && x + deltaX < output.Height)
                                {
                                    Color blur1Pixel = Color.White;
                                    try
                                    {
                                        blur1Pixel = input.GetPixel(x + deltaX, y + deltaY);
                                    }
                                    catch (ArgumentOutOfRangeException e)
                                    {

                                    }

                                    if (blur1Pixel.A == 0)
                                    {
                                        blur = true;
                                    }
                                }



                            }
                        }

                        if (blur)
                        {
                            Color viertelColor = input.GetPixel(x, y);
                            viertelColor = Color.FromArgb(64, viertelColor);

                            // Set the output pixel
                            output.SetPixel(x, y, viertelColor);
                        }
                    }

                }
            }

            Console.WriteLine("Blur - Zweite Stufe");
            // Iterate over all pixels from top to bottom... Blur Stufe 2
            for (int y = 0; y < output.Height; y++)
            {
                //Console.WriteLine("Line "+y);
                // ...and from left to right
                for (int x = 0; x < output.Width; x++)
                {

                    if (input.GetPixel(x, y).A == 255)
                    {

                        Boolean blur = false;
                        Color halbColor = input.GetPixel(x, y);

                        for (int deltaX = -1; deltaX <= 1; deltaX++)
                        {
                            for (int deltaY = -1; deltaY <= 1; deltaY++)
                            {
                                Color blur2Pixel = Color.White;
                                try
                                {
                                    blur2Pixel = input.GetPixel(x + deltaX, y + deltaY);
                                }
                                catch (ArgumentOutOfRangeException e)
                                {

                                }

                                if (blur2Pixel.A == 25 && halbColor.A!=0)
                                {
                                    blur = true;
                                }



                            }
                        }

                        if (blur)
                        {
                            halbColor = Color.FromArgb(128, halbColor);

                            // Set the output pixel
                            output.SetPixel(x, y, halbColor);
                        }
                        
                    }

                }
            }

            output.Save(@"D:\xbox_keyed.png");
        }

    }
}
